# 系统库
import os
import pickle
import requests
import time
import numpy as np

# 第三方库
import cv2
from werkzeug.utils import secure_filename

# 自定义库
from common import config,base_dir
from utils.log import logger

# *********************S 图片格式和相同图片判断区********************************
def allowed_file(filename):
    '''图片文件后缀是否被允许列表'''
    return '.' in filename and \
        filename.rsplit('.', 1)[1] in config['upload']['IMG_ALLOWED_EXTENSIONS']


# pip install opencv-python
# ToDo: 当前只做了图片的上传，文件的上传需要再添加

def calculate_image_hash(image_path):
     
    # 读取图片
    image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)  # 转换为灰度图
    if image is None:
        return
    # 重新调整图片大小    
    image = cv2.resize(image, (8, 8))    
    # 转换为哈希
    image_hash = np.mean(image) 
    return image_hash

def is_same_image(image1_path, image2_path):
    # 计算两张图片的哈希值
    hash1 = calculate_image_hash(image1_path)
    hash2 = calculate_image_hash(image2_path)
    # 比较哈希值
    return hash1 == hash2
    # return hash1.all() == hash2.all()

def dir_same_img(directory,compared_file_path=None):
    image_hashes = set()
    dumplicated = None

    compared_hashes = None
    if compared_file_path !=None: 
        compared_hashes = calculate_image_hash(compared_file_path) 
    for filename in os.listdir(directory):
        if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tif', '.tiff')):
            file_path = os.path.join(directory, filename)
            hash_value = calculate_image_hash(file_path)

            if compared_hashes ==None :               
                if hash_value in image_hashes: 
                    dumplicated = file_path
                    break
                else:
                    image_hashes.add(hash_value)
            else :
                if(hash_value == compared_hashes and file_path != compared_file_path) :
                    dumplicated = file_path
                    break
                else :
                    image_hashes.add(hash_value)
    return dumplicated

def compare_file(file1,file2):
    '''比较两个文件的内容是否一样'''
    import filecmp
    result = filecmp(file1,file2)
    return result 
# *********************E 图片格式和相同图片判断区********************************




# 获取文件内容
def moonshot_get_file_obj(file,open_file=None):
    # 获取到文件对象
    open_file = open_file or file
    print(file)
    if isinstance(file, dict) and 'filename' in file:
        filename = file['filename']
        content_type = file['content_type']
    else: 
        filename = file.filename
        content_type = file.content_type
    form_data = {'file':(filename,open_file,content_type),"purpose":"file-extract"}
    return requests.post('https://api.moonshot.cn/v1/files'  ,headers = {"Authorization": f"Bearer {config['MoonShot']['API_KEY']}"} ,files=form_data)
    
def moonshot_get_file_content(file_id):
    headers = {"Authorization": f"Bearer {config['MoonShot']['API_KEY']}"}    
    url = f'https://api.moonshot.cn/v1/files/{file_id}/content'    
    return requests.get(url,headers=headers)

# 本地上传文件对比图片相似性

def upload_file_to_local(files):
    # 本地文件信息filename 上传的文件名，finalname 上传后的文件名，haveSame 是否有相同的文件,file 文件对象
    
    if files:
        file_info =[]
        try:
            if all(allowed_file(files[index].filename) for index in files):
                # 所有的文件都满足格式要求则上传到本地 否则有一个不满足就报错
                for index in files:
                    file = files[index]
                    filename = secure_filename(file.filename) 
                    res={"filename":filename,"content_type":file.content_type}     
                    # 将文件保存到 static/uploads 目录，文件名同上传时使用的文件名
                    upload_folder = config['upload']['UPLOAD_FOLDER']
                    file_path = os.path.join(base_dir,upload_folder , filename)
                    open_path = file_path
                    if os.path.exists(file_path): 
                        # 文件名相同，则重命名    
                        splited = filename.split('.')
                        file2 = splited[-2]+'.'+str(time.time())+splited[-1]
                        file2_path = os.path.join(base_dir, upload_folder, file2)
                        file.save(file2_path)            
                        # 文件名相同，比较内容
                        if is_same_image(file_path,file2_path):
                            # 图片一致
                            os.remove(file2_path)
                            res['finalname'] = filename
                        else:
                            res['finalname'] = file2
                            open_path = file2_path
                            
                    else :
                        # 文件名不一致直接保存
                        file.save(file_path)
                        # 看看文件内容是否一致 一致就不保存 返回图片路径  
                        same_path = dir_same_img(os.path.join(base_dir,upload_folder),file_path)
                        url_splited = [filename]
                        if same_path :
                            os.remove(file_path)
                            url_splited = same_path.split(upload_folder)
                            open_path = same_path
                        res['finalname'] = url_splited[-1]   
                    res['open_path'] = open_path                
                    file_info.append(res)
                return file_info
            else:
                return {'err':'文件格式不正确','status':201}
        except Exception as e:
            print(e)
            return {'err':f'代码执行异常:{e}','status':203}
    else:
        return {'err':'没有文件需要上传','status':201} 

def get_var_from_file(file_path):
    try:
        with open(file_path, 'rb') as f:
            # 读取并反序列化数据           
            return pickle.load(f)            
    except Exception as e :
        print(f'get_var_from_file error{e}')
        logger.info(f'get_var_from_file error{e}')
        return None
# 写变量到文件
def save_var_to_file(var,file_path):
    try:
        with open(file_path, 'wb') as f:
            pickle.dump(var, f)
    except Exception as e :
        print(f'save_var_to_file error{e}')
        logger.error(f'save_var_to_file error{e}')



# 从本地文件中获取到抽取文件的信息
def get_file_info(filename):
    file_config = get_var_from_file('memory/file_config.json')
    if file_config:
        info =list(filter(lambda x:x['filename']==filename,file_config)) 
        if not info: return None
        return info[0]
    return None
    
# 设置本地文件抽取信息到memory/file_config.json
def set_file_info(exact_content,file_id,filename):
    file_config = get_var_from_file('memory/file_config.json')
    if file_config:
        file_config.append({'exact_content':exact_content,'file_id':file_id,'filename':filename})
    else:
        file_config = [{'exact_content':exact_content,'file_id':file_id,'filename':filename}]    
    save_var_to_file(file_config,'memory/file_config.json')
# 删除本地文件 files_info = [{'open_path':'','filename':''}]
def remove_local_file(files_info):
    for item in files_info:
        os.remove(item['open_path'])

def set_files_msg(is_file_msg,msg_id,user_id):
     if is_file_msg:
            # 记录本地文件对应的会话id和用户
            session = get_var_from_file('memory/history.json')
            session= session if session else {}
            session[msg_id] = user_id
            save_var_to_file(session,'memory/history.json')